<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="default" />
        <meta name="theme-color" content="#000000" />
        <meta name="name" content="PyScript/Panel Streaming Demo" />

        <title>PyScript/Panel Streaming Demo</title>
        <link rel="icon" type="image/x-icon" href="./favicon.ico" />

        <link
            rel="stylesheet"
            href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
            type="text/css"
        />
        <link
            rel="stylesheet"
            href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/widgets.css"
            type="text/css"
        />
        <link
            rel="stylesheet"
            href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/markdown.css"
            type="text/css"
        />

        <script
            type="text/javascript"
            src="https://unpkg.com/tabulator-tables@4.9.3/dist/js/tabulator.js"
        ></script>
        <script
            type="text/javascript"
            src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"
        ></script>
        <script
            type="text/javascript"
            src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"
        ></script>
        <script
            type="text/javascript"
            src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"
        ></script>
        <script
            type="text/javascript"
            src="https://unpkg.com/@holoviz/panel@0.13.1/dist/panel.min.js"
        ></script>
        <script type="text/javascript">
            Bokeh.set_log_level("info");
        </script>

        <link
            rel="stylesheet"
            href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"
        />
        <link
            rel="stylesheet"
            href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/bootstraptemplate/bootstrap.css"
        />
        <link
            rel="stylesheet"
            href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/defaulttheme/default.css"
        />

        <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>

        <link
            rel="stylesheet"
            href="https://pyscript.net/latest/pyscript.css"
        />
        <script defer src="https://pyscript.net/latest/pyscript.js"></script>
        <link rel="stylesheet" href="./assets/css/examples.css" />
    </head>

    <body>
        <nav class="navbar" style="background-color: #000000">
            <div class="app-header">
                <a href="/">
                    <img src="./logo.png" class="logo" />
                </a>
                <a class="title" href="" style="color: #f0ab3c"
                    >Panel Streaming Demo</a
                >
            </div>
        </nav>
        <section class="pyscript">
            <div class="row overflow-hidden" id="content">
                <div class="col mh-100 float-left" id="main">
                    <div class="bk-root" id="controls"></div>
                    <div class="row">
                        <div class="bk-root" id="table"></div>
                        <div class="bk-root" id="plot"></div>
                    </div>
                </div>
            </div>

            <py-tutor>
                <py-config>
                    packages = [
                      "https://cdn.holoviz.org/panel/0.14.3/dist/wheels/bokeh-2.4.3-py3-none-any.whl",
                      "numpy",
                      "pandas",
                      "panel==0.13.1"
                    ]
                    plugins = [
                      "https://pyscript.net/latest/plugins/python/py_tutor.py"
                    ]
                </py-config>

                <py-script>
                    import panel as pn
                    import numpy as np
                    import pandas as pd

                    from bokeh.models import ColumnDataSource
                    from bokeh.plotting import figure

                    df = pd.DataFrame(np.random.randn(10, 4), columns=list('ABCD')).cumsum()

                    rollover = pn.widgets.IntInput(name='Rollover', value=15)
                    follow = pn.widgets.Checkbox(name='Follow', value=True, align='end')

                    tabulator = pn.widgets.Tabulator(df, height=450, width=400).servable(target='table')

                    def color_negative_red(val):
                        """
                        Takes a scalar and returns a string with
                        the css property `'color: red'` for negative
                        strings, black otherwise.
                        """
                        color = 'red' if val < 0 else 'green'
                        return 'color: %s' % color

                    tabulator.style.applymap(color_negative_red)

                    p = figure(height=450, width=600)

                    cds = ColumnDataSource(data=ColumnDataSource.from_df(df))

                    p.line('index', 'A', source=cds, line_color='red')
                    p.line('index', 'B', source=cds, line_color='green')
                    p.line('index', 'C', source=cds, line_color='blue')
                    p.line('index', 'D', source=cds, line_color='purple')

                    def stream():
                        data = df.iloc[-1] + np.random.randn(4)
                        tabulator.stream(data, rollover=rollover.value, follow=follow.value)
                        value = {k: [v] for k, v in tabulator.value.iloc[-1].to_dict().items()}
                        value['index'] = [tabulator.value.index[-1]]
                        cds.stream(value)

                    cb = pn.state.add_periodic_callback(stream, 200)

                    pn.pane.Bokeh(p).servable(target='plot')
                    pn.Row(cb.param.period, rollover, follow, width=400).servable(target='controls')
                </py-script>
            </py-tutor>
        </section>
    </body>
</html>
